package com.lwl.java.base;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.Random;

/**
 * @author lwl
 * @Description TODO
 * @date 2025/9/6 15:40
 */
public class CountDownLatchDemo {


    public static void main(String[] args) throws InterruptedException {
        final int runnerCount = 4;
        // 发令枪倒计时 (1表示裁判发令)
        CountDownLatch startLatch = new CountDownLatch(1);
        // 运动员完成倒计时
        CountDownLatch finishLatch = new CountDownLatch(runnerCount);
        ExecutorService executor = Executors.newFixedThreadPool(runnerCount);
        Random random = new Random();

        // 运动员线程
        for (int i = 0; i < runnerCount; i++) {
            final int runnerId = i;
            executor.execute(() -> {
                try {
                    System.out.println("运动员 " + runnerId + " 准备就绪，等待发令枪");
                    startLatch.await(); // 等待发令枪响
                    System.out.println("运动员 " + runnerId + " 开始奔跑");
                    Thread.sleep(random.nextInt(2000) + 1000); // 模拟跑步时间
                    System.out.println("运动员 " + runnerId + " 到达终点");
                    finishLatch.countDown(); // 完成计数减一
                    // 一个线程可以 coundDown 多次
//                    finishLatch.countDown(); // 完成计数减一
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }

        Thread.sleep(1000); // 裁判准备时间
        System.out.println("裁判：发令枪响！");
        startLatch.countDown(); // 发令枪响，运动员开始跑

        System.out.println("裁判：等待所有运动员完成比赛...");
        finishLatch.await(); // 等待所有运动员完成
        System.out.println("裁判：所有运动员均已完成比赛，开始汇总成绩");

        executor.shutdown();
    }
}
